package com.wonder.app.service.impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vtuzx.core.utils.VtuzxUtil;
import com.wonder.admin.service.IVtuzxKingdeeService;
import com.wonder.app.domain.*;
import com.wonder.app.mapper.*;
import com.wonder.app.request.PrdReturnRequest;
import com.wonder.app.service.MaterialService;
import com.wonder.app.service.PrdReturnDetailService;
import com.wonder.app.service.PrdReturnService;
import com.wonder.app.service.SyncKingdeeOrderService;
import com.wonder.common.utils.MapToEntity;
import com.wonder.constant.BillType;
import com.wonder.constant.IXqcConst;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class PrdReturnServiceImpl extends ServiceImpl<PrdReturnDao, PrdReturn> implements PrdReturnService {
    private static final Logger _logger = LoggerFactory.getLogger(PrdReturnServiceImpl.class);

    @Autowired
    private PrdReturnService prdReturnService;
    @Autowired
    private  PrdReturnDao prdReturnDao;
    @Autowired
    private PrdReturnDetailDao prdReturnDetailDao;

    @Autowired
    private PpBomDao ppBomDao;

    @Autowired
    private PrdReturnDetailService prdReturnDetailService;

    @Autowired
    private IVtuzxKingdeeService vtuzxKingdeeService;

    @Autowired
    private MaterialService materialService;

    @Autowired
    private SyncKingdeeOrderService syncKingdeeOrderService;

    @Autowired
    private PrdFeedDetailDao prdFeedDetailDao;

    @Autowired
    private PrdFeedDao prdFeedDao;

    @Autowired
    private PrdPickDao prdPickDao;

    @Autowired
    private PickDetailDao pickDetailDao;

    @Autowired
    private SfcProplanDao sfcProplanpDao;

    @Autowired
    private SfcproplanDetailDao sfcproplanDetailDao;

    @Override
    public IPage<PrdReturn> selectList(PrdReturnRequest prdReturnRequest, Page<PrdReturn> page) {
        LambdaQueryWrapper<PrdReturn> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (prdReturnRequest.getFBillNo() != null){
            lambdaQueryWrapper.like(PrdReturn::getFBILLNO,prdReturnRequest.getFBillNo());
        }
        if (prdReturnRequest.getFKDBILLNO() != null){
            lambdaQueryWrapper.like(PrdReturn::getFKDBILLNO,prdReturnRequest.getFKDBILLNO());
        }
        if (prdReturnRequest.getFBILLNOMO() != null) {
            lambdaQueryWrapper.like(PrdReturn::getFBILLNOMO, prdReturnRequest.getFBILLNOMO());
        }
        if (prdReturnRequest.getFCREATEUSER() != null){
            lambdaQueryWrapper.like(PrdReturn::getFCREATEUSER,prdReturnRequest.getFCREATEUSER());
        }
        if (prdReturnRequest.getFWORKSHOPNAME() != null) {
            lambdaQueryWrapper.like(PrdReturn::getFWORKSHOPNAME, prdReturnRequest.getFWORKSHOPNAME());
        }
        if (prdReturnRequest.getFDATE() != null){
            Date[] orderDate = prdReturnRequest.getFDATE();
            if(orderDate.length>0)
                lambdaQueryWrapper.ge(PrdReturn::getFDATE, orderDate[0]);
            if(orderDate.length==2)
                lambdaQueryWrapper.le(PrdReturn::getFDATE,orderDate[1]);
        }
        lambdaQueryWrapper.orderByDesc(PrdReturn::getFDATE);
        Page<PrdReturn> selectPage = this.baseMapper.selectPage(page, lambdaQueryWrapper);
        return selectPage;
    }


    /**
     * 生产退料单明细详情
     * @param map
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> getPrdReturnDetail(Map<String, Object> map) {
        String billNo = map.get("billNo").toString();
        PrdReturn prdreturnform = prdReturnDao.selectOne(new LambdaQueryWrapper<PrdReturn>()
                .eq(PrdReturn::getFBILLNO,billNo));
        List<PrdReturnDetail> prdreturndetailList = prdReturnDetailDao.selectList(new LambdaQueryWrapper<PrdReturnDetail>()
                .eq(PrdReturnDetail::getFBILLNO,billNo));
        Map<String,Object> data = new HashMap<>();
        data.put("data",prdreturnform);
        data.put("dataList",prdreturndetailList);
        return data;
    }

    /**
     * 根据工序计划单号获取领料和补料信息，用于退料
     * @param map
     * @return
     */
    @Override
    public Map<String, Object> getPrdReturnList(Map<String, Object> map) {
        String moBillNo = VtuzxUtil.getString(map,"moBillNo");//生产订单号
        //查询领料
        List<PickDetail> pickDetailList = pickDetailDao.selectList(new LambdaQueryWrapper<PickDetail>()
                .eq(PickDetail::getMOBILLNO, moBillNo)
                .eq(PickDetail::getTEMP, false));
        //查询补料
        List<PrdFeedDetail> feedDetailList = prdFeedDetailDao.selectList(new LambdaQueryWrapper<PrdFeedDetail>()
                .eq(PrdFeedDetail::getMOBILLNO, moBillNo)
                .eq(PrdFeedDetail::getTEMP, false));
        List<Map<String,Object>> dataList = new ArrayList<>();
        if(!VtuzxUtil.isEmpty(pickDetailList)){
            for (PickDetail pickDetail : pickDetailList){
                Map<String, Object> dataMap = MapToEntity.objectToMap(pickDetail);
                dataMap.put("maxQty",VtuzxUtil.getDouble(dataMap,"finfactqty"));//用于前端校验
                dataList.add(dataMap);
            }
        }
        if(!VtuzxUtil.isEmpty(feedDetailList)){
            for (PrdFeedDetail feedDetail : feedDetailList){
                Map<String, Object> dataMap = MapToEntity.objectToMap(feedDetail);
                dataMap.put("finfactqty",VtuzxUtil.getDouble(dataMap,"factualqty"));
                dataMap.put("maxQty",VtuzxUtil.getDouble(dataMap,"factualqty"));//用于前端校验
                dataList.add(dataMap);
            }
        }
        Map<String,Object> data = new HashMap<>();
        data.put("data",dataList);

        return data;
    }

    /**
     * 添加退料详情数据(临时)
     * @param map
     * @return
     */
    @Override
    public Boolean addPrdReturnDetail(Long user_id,Map<String, Object> map) throws Exception{
        List<Map<String,Object>> data = VtuzxUtil.getObject(map,"boxList");
        List<PrdReturnDetail> returnDetailList = new ArrayList<>();
        for (Map<String,Object> dataMap : data){
            PrdReturnDetail prdReturnDetail = new PrdReturnDetail();
            prdReturnDetail.setFMATERIALNUMBER(VtuzxUtil.getString(dataMap,"fmaterialnumber"));
            prdReturnDetail.setFMATERIALNAME(VtuzxUtil.getString(dataMap,"fmaterialname"));
            prdReturnDetail.setFSPECIFICATION(VtuzxUtil.getString(dataMap,"fspecification"));
            prdReturnDetail.setFUNITID(VtuzxUtil.getString(dataMap,"funitid"));
            prdReturnDetail.setFUNITNAME(VtuzxUtil.getString(dataMap,"funitname"));
            prdReturnDetail.setFAPPQTY(VtuzxUtil.getDouble(dataMap,"finfactqty"));
            prdReturnDetail.setFACTQTY(VtuzxUtil.getDouble(dataMap,"finfactqty"));
            prdReturnDetail.setFLOT(VtuzxUtil.getString(dataMap,"flot"));
            prdReturnDetail.setTEMP(true);
            prdReturnDetail.setUSERID(user_id);
            prdReturnDetail.setMOBILLNO(VtuzxUtil.getString(dataMap,"mobillno"));
            prdReturnDetail.setCREATETIME(new Date());
            returnDetailList.add(prdReturnDetail);
        }
        boolean saveBatch = prdReturnDetailService.saveBatch(returnDetailList);
        return saveBatch;
    }

    /**
     * 获取补料单临时数据
     * @param map
     * @param user_id
     * @return
     */
    @Override
    public Map<String, Object> getPrdReturnTemp(Map<String, Object> map, Long user_id) {
        String billNo = map.get("billNo").toString();
        SfcProplan sfcProplan = sfcProplanpDao.selectOne(new LambdaQueryWrapper<SfcProplan>()
                .eq(SfcProplan::getBillNo,billNo));
        if(null == sfcProplan){
            throw new RuntimeException("单号错误请重试");
        }
        //详情数据展示补料中的临时数据信息
        List<PrdReturnDetail> detailList = prdReturnDetailDao.selectList(new LambdaQueryWrapper<PrdReturnDetail>()
                .eq(PrdReturnDetail::getMOBILLNO, sfcProplan.getMoBillNo())
                .eq(PrdReturnDetail::getTEMP, true));

        Map<String,Object> data = new HashMap<>();
        data.put("data",sfcProplan);
        data.put("dataList",detailList);
        return data;
    }

    /**
     * 删除退料中的临时数据
     * @param userName
     * @param map
     * @return
     */
    @Override
    public Boolean deleteReturnDetailTemp(String userName, Map<String, Object> map) {
        String moBillNo = VtuzxUtil.getString(map,"moBillNo");
        Map<String,Object> pickDetail = VtuzxUtil.getObject(map,"pickDetail");
        int detailId = VtuzxUtil.getInt(pickDetail,"id");
        //删除表中的临时数据
        boolean b = prdReturnDetailService.removeById(detailId);
        return b;
    }

    /**
     * 生成退料单
     * @param userName
     * @param map
     * @return
     */
    @Override
    public Boolean createReturnBill(String userName, Map<String, Object> map) throws Exception {
        Map<String,Object> planData = VtuzxUtil.getObject(map,"planData");
        List<Map<String,Object>> detailList = VtuzxUtil.getObject(map,"detail");
        String returnBillNo =  IXqcConst.createBillNo(BillType.SCTL);//生成中台退料
        String FBILLNOMO = VtuzxUtil.getString(planData,"moBillNo");//生产订单号
        String BIllNo = VtuzxUtil.getString(planData,"billNo");//工序计划单号
        //获取车间信息
        List<SfcproplanDetail> sfcproplanDetailList = sfcproplanDetailDao.selectList(new LambdaQueryWrapper<SfcproplanDetail>()
                .eq(SfcproplanDetail::getBillNo, BIllNo));
        String workNo = "";
        String workName = "";
        if(!VtuzxUtil.isEmpty(sfcproplanDetailList)){
            workName = sfcproplanDetailList.get(0).getDepartName();
            workNo = sfcproplanDetailList.get(0).getDepartNo();

        }

        List<PrdReturnDetail> returnDetailList = new ArrayList<>();

        for (Map<String,Object> data : detailList ){
            PrdReturnDetail prdReturnDetail = MapToEntity.mapToBean(data,PrdReturnDetail.class);
            prdReturnDetail.setTEMP(false);
            prdReturnDetail.setFBILLNO(returnBillNo);//退料单号
            returnDetailList.add(prdReturnDetail);
        }

        PrdReturn prdReturn = new PrdReturn();
        prdReturn.setFBILLNO(returnBillNo);
        prdReturn.setFDATE(new DateTime());
        prdReturn.setFCREATEUSER(userName);
        prdReturn.setFSTATE(false);
        prdReturn.setFBILLNOMO(FBILLNOMO);//生产订单单号
        prdReturn.setFWORKSHOPNAME(workName);
        prdReturn.setFWORKSHOPNO(workNo);
        //保存到数据库
        boolean savehead = prdReturnService.save(prdReturn);
        boolean saveBatch = prdReturnDetailService.saveOrUpdateBatch(returnDetailList);

        return savehead && saveBatch;
    }

    /**
     * 包装间生成退料单
     * @param userName
     * @param type
     * @return
     * @throws Exception
     */
    @Override
    public Boolean createReturnBillPackage(Long user_id,String userName, SfcOptrptPackage sfcOptrptPackage, String type,String kingdeeNo) throws Exception {
        List<PrdReturn> returnList = new ArrayList<>();
        List<PrdReturnDetail> returnDetailList = new ArrayList<>();
        String returnBillNo =  IXqcConst.createBillNo(BillType.SCTL);//生成中台退料
        String FBILLNOMO = sfcOptrptPackage.getMoBillNo();//生产订单号

        Double count = 0.0;
        String stockNo = "";
        String stockName = "";
        //报废类型退料数量为报废数量，仓库为回材库
        //外协不良类型退料数量为外协不良数量，仓库为报废品仓库
        //返修类型退料数量为返修数量，仓库为待不良品返修
        if ("fail".equals(type)){
            count = sfcOptrptPackage.getFailQty();
            stockName = "回材库";
            stockNo = "CK023";
        }
//        else if ("out".equals(type)){
//            count = sfcOptrptPackage.getOutFailQty();
//            stockName = "报废品仓库（不能作为回材）";
//            stockNo = "CK022";
//        } else if ("return".equals(type)){
//            count = sfcOptrptPackage.getReturnQty();
//            stockName = "不良品待返修";
//            stockNo = "CK021";
//        }
        String materialNo = sfcOptrptPackage.getMaterialNo();
        List<String> materialNoList = new ArrayList<>();
        materialNoList.add(materialNo);
        //根据物料编码查询物料名称等信息
        List<Map<String, Object>> materialList = materialService.getMaterialByNo(materialNoList);
        if (VtuzxUtil.isEmpty(materialList)){
            throw new RuntimeException(String.format("物料编码:%s不存在",sfcOptrptPackage.getMaterialNo()));
        }
        //将查询到的物料信息转成map
        Map<String, Object> materialToMap = changeMaterialToMap(materialList);
        Map<String,Object> materialMap = VtuzxUtil.getObject(materialToMap,sfcOptrptPackage.getMaterialNo());

        PrdReturnDetail prdReturnDetail = new PrdReturnDetail();
        prdReturnDetail.setFBILLNO(returnBillNo);
        prdReturnDetail.setFMATERIALNUMBER(materialNo);
        prdReturnDetail.setFMATERIALNAME(VtuzxUtil.getString(materialMap,"FNAME"));
        prdReturnDetail.setFSTOCKNUMBER(VtuzxUtil.getString(materialMap,"FSPECIFICATION"));
        prdReturnDetail.setFUNITID(VtuzxUtil.getString(materialMap,"unitNo"));
        prdReturnDetail.setFUNITNAME(VtuzxUtil.getString(materialMap,"unitName"));
        prdReturnDetail.setFAPPQTY(count);
        prdReturnDetail.setFACTQTY(count);
        prdReturnDetail.setFSTOCKNUMBER(stockNo);
        prdReturnDetail.setFSTOCKNAME(stockName);
        prdReturnDetail.setFLOT("");
        prdReturnDetail.setTEMP(false);
        prdReturnDetail.setMOBILLNO(FBILLNOMO);
        prdReturnDetail.setCREATETIME(new Date());
        returnDetailList.add(prdReturnDetail);


        PrdReturn prdReturn = new PrdReturn();
        prdReturn.setFBILLNO(returnBillNo);
        prdReturn.setFDATE(new DateTime());
        prdReturn.setFCREATEUSER(userName);
        prdReturn.setFSTATE(false);
        prdReturn.setFBILLNOMO(FBILLNOMO);//生产订单单号
        prdReturn.setFWORKSHOPNAME("包装车间");
        prdReturn.setFWORKSHOPNO("BZ");
        returnList.add(prdReturn);

        //保存到数据库
        boolean savehead = prdReturnService.saveOrUpdateBatch(returnList);
        boolean saveBatch = prdReturnDetailService.saveOrUpdateBatch(returnDetailList);
        //传金蝶退料
        try {
            syncKingdeeOrderService.syncPrdReturnBao(user_id,prdReturn,returnDetailList,kingdeeNo,sfcOptrptPackage);
        } catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }


        return savehead && saveBatch;
    }

    /**
     * key;物料编码 val:物料相关信息(map)
     * @param materialList
     * @return
     */
    private Map<String,Object> changeMaterialToMap(List<Map<String,Object>> materialList){
        Map<String,Object> dataMap = new HashMap<>();
        for (Map<String,Object> data : materialList){
            String FNUMBER = VtuzxUtil.getString(data,"FNUMBER");
            String FNAME = VtuzxUtil.getString(data,"FNAME");
            String FSPECIFICATION = VtuzxUtil.getString(data,"FSPECIFICATION");
            String unitNo = VtuzxUtil.getString(data,"unitNo");//单位编码
            String unitName = VtuzxUtil.getString(data,"unitName");//单位名称
            String FDOCUMENTSTATUS = VtuzxUtil.getString(data,"FDOCUMENTSTATUS");//审核状态
            String FFORBIDSTATUS = VtuzxUtil.getString(data,"FFORBIDSTATUS");//禁用状态
            Map<String,Object> materialMap = new HashMap<>();
            materialMap.put("FNUMBER",FNUMBER);
            materialMap.put("FNAME",FNAME);
            materialMap.put("FSPECIFICATION",FSPECIFICATION);
            materialMap.put("unitNo",unitNo);
            materialMap.put("unitName",unitName);
            materialMap.put("FDOCUMENTSTATUS",FDOCUMENTSTATUS);
            materialMap.put("FFORBIDSTATUS",FFORBIDSTATUS);
            dataMap.put(FNUMBER,materialMap);
        }
        return dataMap;
    }
}

